﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CSA.Lib;

namespace CSA.Operator
{
    public class ReSelectOperator : ICSOperator
    {
        #region Fields
        CSPopulation m_OperatePopulation = null;
        String m_CurUsedFunctionName = "";
        Hashtable m_Parameters = new Hashtable();     //map<string,CSParameter*>	
        Hashtable m_FunctionNames = new Hashtable();
        #endregion

        #region Properties

        public String Name
        {
            get { return "ReSelectOperator"; }
        }

        public String Caption
        {
            get { return global::CSA.Operator.TextString.ReSelectOperatorCaption; }
        }

        public String Description
        {
            get { return global::CSA.Operator.TextString.ReSelectOperatorDes; }
        }


        public String Library
        {
            get { return "CSA.Operator"; }
        }

        public Hashtable Get_Parameters(String nFunctionName)
        {
            String nValidateName = "";
            if (nFunctionName.Trim() == "" || !m_FunctionNames.Contains(nFunctionName))
            {
                nValidateName = "DefaultReselectFunction";
            }
            else
            {
                nValidateName = nFunctionName;
            }
            CSFuntionInfo nDefulatParas = (CSFuntionInfo)m_FunctionNames[nValidateName];
            return nDefulatParas.Parameters;
        }

        public OperatorType OperatorType
        {
            get { return OperatorType.enumReSelectOperator; }
        }

        public Hashtable FunctionNames
        {
            get { return m_FunctionNames; }
        }

        public CSFuntionInfo CustomAntibodyOperator
        {
            get { return null; }
            set { }
        }

        public bool UseCustomAntibodyOperator
        {
            get { return false; }
        }

        #endregion


        public ReSelectOperator()
        {
            InitialParameters();
        }

        ~ReSelectOperator()
        {
            m_Parameters.Clear();
        }

        public bool Execute(CSPopulation nOperatePopulation, ref String nErrorStr, String nMethodName = "")
        {
            //Obtain the population information
            m_OperatePopulation = nOperatePopulation;
            if (nMethodName.Trim() == "" || !m_FunctionNames.Contains(nMethodName))
            {
                m_CurUsedFunctionName = "DefaultReselectFunction";

            }
            else
            {
                m_CurUsedFunctionName = nMethodName;
            }
            CSFuntionInfo nDefulatParas = (CSFuntionInfo)m_FunctionNames[m_CurUsedFunctionName];
            if (m_CurUsedFunctionName == "DefaultReselectFunction")
            {
                return DefaultFunction(ref nErrorStr);
            }
            return true;
        }        

        private bool DefaultFunction(ref String nErrorStr)
        {
            try
            {
                List<CSAntibody> nNewPop = m_OperatePopulation.NewAntibodies;
                List<CSAntibody> nMemoryPop = m_OperatePopulation.MemoryAntibodies;            
                Int32 nMemoryIt = nMemoryPop.Count - 1;            
                Int32 nNewMemoryIt;
                bool nHasMemory = true;           
                if (nMemoryIt > -1)
                {
                    nHasMemory = true;
                }             
                for (nNewMemoryIt = 0; nNewMemoryIt < nNewPop.Count; )
                {
                    CSAntibody nCurAntibody = nNewPop[nNewMemoryIt];
                    if (nHasMemory)
                    {
                        CSAntibody nMinAb = nMemoryPop[nMemoryIt];
                        if (nMinAb.Affinity < nCurAntibody.Affinity)
                        {
                            CSAntibody nTempAb = nCurAntibody;
                            nMemoryPop[nMemoryIt] = nTempAb;
                            ++nNewMemoryIt;
                        }
                        --nMemoryIt;
                        if (nMemoryIt == 0)
                        {
                            nHasMemory = false;
                        }
                    }                  
                    else
                    {
                        break;
                    }
                }
                nNewPop.Clear();
                nMemoryPop.Sort(new AntibodyCompare());          
                return true;
            }
            catch (Exception ex)
            {
                nErrorStr = ex.Message;
                return false;
            }
        }

        public void InitialParameters()
        {
            m_FunctionNames.Clear();
            //Add parameters
            CSFuntionInfo m_DefaultFunctionInfo = new CSFuntionInfo();
            m_DefaultFunctionInfo.Caption = global::CSA.Operator.TextString.DefaultFunction;
            m_DefaultFunctionInfo.Description =global::CSA.Operator.TextString.ReSelectOperatorDes;
            m_DefaultFunctionInfo.Name = "DefaultReselectFunction";     
            Hashtable nStandardFunctionPara = new Hashtable();         
            m_DefaultFunctionInfo.Parameters = nStandardFunctionPara;
            m_FunctionNames.Add(m_DefaultFunctionInfo.Name, m_DefaultFunctionInfo);
        }
    }
}

